/*
 *  File : AlphaNumericKey.java
 *  Created By : madhurt
 *  Created On : Oct 13, 2010
 *  Yahoo! 2010
 */
package com.gebogebo.key;

/**
 *
 * @author madhurt
 */
public class AlphaNumericKey implements SingleValueKey<Character> {

    private char[] keySet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_".toCharArray();
    private final int MAX_VALUES = keySet.length;   //0-based
    private int nextValue = 0;
    private Character currentValue = keySet[0];

    public synchronized Character nextValue() throws ValueOverflowException {
        if (nextValue < MAX_VALUES) {
            return (currentValue = keySet[nextValue++]);
        }

        throw new ValueOverflowException();
        //assert false : "Should have never reached here";
        //throw new IllegalStateException("Execution should have never reached this point");
    }

    public synchronized Character reset() {
        nextValue = 1;
        return (currentValue = keySet[0]);
    }

    public synchronized Character currentValue() {
        if (nextValue == 0) {
            //the first default value has been accessed
            nextValue++;
        }
        return currentValue;
    }

    public Character[] getkeySet() {
        return copyKeySet();
    }

    public static void main(String[] args) throws Exception {
        AlphaNumericKey k = new AlphaNumericKey();
        try {
            for (int i = 0; i < 64; i++) {
                System.out.println(k.nextValue());
                assert k.currentValue().equals(k.keySet[i]) : "failed for " + i + ", got " + k.currentValue();
            }
        } catch (ValueOverflowException ex) {
            assert k.currentValue().equals(k.keySet[k.keySet.length - 1]) : "failed for last value, got " + k.currentValue();
        }

        assert k.reset().equals(k.keySet[0]);
        assert k.currentValue().equals(k.keySet[0]);

        try {
            for (int i = 1; i < 64; i++) {
                System.out.println(k.nextValue());
                assert k.currentValue().equals(k.keySet[i]) : "failed for " + i + ", got " + k.currentValue();
            }
        } catch (ValueOverflowException ex) {
            assert k.currentValue().equals(k.keySet[k.keySet.length - 1]) : "failed for last value";
        }
    }

    private Character[] copyKeySet() {
        final Character[] result = new Character[keySet.length];
        for (int i = 0; i < keySet.length; i++) {
            result[i] = new Character(keySet[i]);
        }
        return result;
    }
}
